//
// Created by DELL on 2024/2/29.
//

#include <iostream>

class Buffer
{
public:
    Buffer() = default;
    explicit Buffer(int size)
        : dataSize(size)
    {
        buffer = new uint8_t[size]{};
    }
    Buffer(const Buffer& buf)
    {
        this->dataSize = buf.dataSize;
        this->buffer = new uint8_t[dataSize];
        memcpy(this->buffer, buf.buffer, dataSize);
    }
    ~Buffer()
    {
        if (this->buffer != nullptr)
        {
            delete[] this->buffer;
        }
    }
    Buffer& operator=(const Buffer& buf)
    {
        if (this == &buf)
        {
            return *this;
        }

        if (this->buffer != nullptr)
        {
            delete[] this->buffer;
        }

        this->dataSize = buf.dataSize;
        this->buffer = new uint8_t[dataSize];
        memcpy(this->buffer, buf.buffer, dataSize);

        return *this;
    }

    Buffer(Buffer&& buf) noexcept
    {
        this->buffer = buf.buffer;
        this->dataSize = buf.dataSize;

        buf.buffer = nullptr;
        buf.dataSize = 0;
    }

    Buffer& operator=(Buffer&& buf) noexcept
    {
        if (this == &buf)
        {
            return *this;
        }

        if (this->buffer != nullptr)
        {
            delete[] this->buffer;
        }

        this->dataSize = buf.dataSize;
        this->buffer = buf.buffer;

        buf.buffer = nullptr;
        buf.dataSize = 0;
        return *this;
    }

    void resize(int size)
    {
        if (this->dataSize == size)
        {
            return;
        }
        else if(this->buffer != nullptr)
        {
            delete this->buffer;
        }
        this->buffer = new uint8_t[size]{};
        this->dataSize = size;
    }

    uint8_t* data()
    {
        return this->buffer;
    }

    [[nodiscard]] const uint8_t* data() const
    {
        return this->buffer;
    }

    [[nodiscard]] int getSize() const
    {
        return this->dataSize;
    }

private:
    uint8_t* buffer{};
    int dataSize{0};
};


int main(int count, const char* args[])
{
    Buffer buffer1(10);
    Buffer buffer2 = buffer1;
    buffer1.resize(15);
    buffer2 = buffer1;

    Buffer buffer3(std::move(buffer2));

    buffer2.resize(20);
    buffer3 = std::move(buffer2);

    std::cout << "buffer3:" << buffer3.getSize() << std::endl;

    return 0;
}
